<?php
/*
*$config['prefix']
*$config['memcache']['server']
*$config['memcache']['pconnect']
*$config['memcache']['port']
*$config['eaccelerator']=0
*$config['xcache']=0
*
*
*
*/

//缓存相关配置设置
class Cache
{
	var $config;
	var $extension = array();
	var $memory;
	var $prefix;
	var $type;
	var $keys;
	var $enable = false;
	
	function __construct(){
		$this->extension['eaccelerator'] = function_exists('eaccelerator_get');
		$this->extension['xcache'] = function_exists('xcache_get');
		$this->extension['memcache'] = extension_loaded('memcache');
	}
	
	function init($config) {

		$this->config = $config;
		$this->prefix = empty($config['prefix']) ? substr(md5($_SERVER['HTTP_HOST']), 0, 6).'_' : $config['prefix'];
		$this->keys = array();

		if($this->extension['memcache'] && !empty($config['memcache']['server']) && !empty($config['memcache']['port'])) {
			require_once('cache/class_memcache.php');
			$this->memory = new sys_memcache();
			$this->memory->init($this->config['memcache']);
			if(!$this->memory->enable) {
				$this->memory = null;
			}
		}

		if(!is_object($this->memory) && $this->extension['eaccelerator'] && $this->config['eaccelerator']) {
			require_once('cache/class_eaccelerator.php');
			$this->memory = new sys_eaccelerator();
			$this->memory->init(null);
		}

		if(!is_object($this->memory) && $this->extension['xcache'] && $this->config['xcache']) {
			require_once('cache/class_xcache.php');
			$this->memory = new sys_xcache();
			$this->memory->init(null);
		}

		if(is_object($this->memory)) {
			$this->enable = true;
			$this->type = str_replace('sys_', '', get_class($this->memory));
			$this->keys = $this->get('memory_system_keys');
			$this->keys = !is_array($this->keys) ? array() : $this->keys;
		}
	}

	function get($key) {
		$ret = null;
		
		if($this->enable) {
			$ret = $this->memory->get($this->_key($key));
			if(!is_array($ret)) {
				$ret = null;
				if(array_key_exists($key, $this->keys)) {
					unset($this->keys[$key]);
					$this->memory->set($this->_key('memory_system_keys'), array($this->keys));
				}
			} else {
				return $ret[0];
			}
		}else {
			return $this->_sqlget($key);
		}

		return $ret;
	}
	
	function _sqlget($key){
			$data = null;
			$cache = M('Cache');
			$map['key'] = array('eq',$key);
			$cachedata = $cache->where($map)->find();
			if(empty($cachedata)) {
				return null;
			}
	
			$data = unserialize($cachedata['value']);
			if($cachedata['ttl'] && ($cachedata['uptime'] < time() - $cachedata['ttl'])) {
				return null;
			}
		return $data;
	}
	function set($key, $value, $ttl = 0) {

		$ret = null;
		if($this->enable) {
			$ret = $this->memory->set($this->_key($key), array($value), $ttl);
			if($ret) {
				$this->keys[$key] = true;
				$this->memory->set($this->_key('memory_system_keys'), array($this->keys));
			}
		}else {
			return $this->_sqlset($key, $value, $ttl);
		}
		return $ret;
	}
	
	function _sqlset($key , $value , $ttl){
		$cache = M('Cache');
		$value = serialize($value);
		$cachedata = array(
			'key'=>$key,
			'value'=>$value,
			'uptime'=>time(),
			'ttl'=>$ttl
		);
		$cache->add($cachedata,null,true);
		return true;
	}
	
	function rm($key) {
		$ret = null;
		if($this->enable) {
			$ret = $this->memory->rm($this->_key($key));
			unset($this->keys[$key]);
			$this->memory->set($this->_key('memory_system_keys'), array($this->keys));
		}else {
			return $this->_sqlrm($key);
		}
		return $ret;
	}
	
	function _sqlrm($key){
		$cache = M('Cache');
		$map['key'] = array('eq',$key);
		$cache->where($map)->delete();
		return true;
	}
	function clear() {
		if($this->enable && is_array($this->keys)) {
			$this->keys['memory_system_keys'] = true;
			foreach ($this->keys as $k => $v) {
				$this->memory->rm($this->_key($k));
			}
		}else {
			return $this->_sqlclear();
		}
		$this->keys = array();
		return true;
	}
	
	function _sqlclear(){
		$cache = M('Cache');
		$prefix = C('DB_PREFIX');
		$cache->query("TRUNCATE TABLE {$prefix}cache");
		return true;
	}
	
	function _key($str) {
		return ($this->prefix).$str;
	}

}

?>